<template>
  <div
    class="home"
    v-loading="loading"
  >
    <Particle></Particle>
    <div class="button_flex">
      <el-select
        v-model="model"
        size="small"
        placeholder="请选择建模"
      >
        <el-option
          v-for="item in models"
          :key="item.path"
          :label="item.name"
          :value="item.path"
        >
        </el-option>
      </el-select>
      <el-select
        v-model="motion"
        size="small"
        placeholder="请选择动作"
      >
        <el-option
          v-for="item in motions"
          :key="item.path"
          :label="item.name"
          :value="item.path"
        >
        </el-option>

      </el-select>
      <el-button
        size="small"
        type="primary"
        @click="play"
      >播放</el-button>
    </div>
    <div
      ref="sceneElement"
      class="scene_element"
    ></div>
  </div>
</template>

<script>
import Particle from '@/components/Particle'
import * as THREE from 'three'
import { MMDLoader } from 'three/examples/jsm/loaders/MMDLoader.js'
import { MMDAnimationHelper } from 'three/examples/jsm/animation/MMDAnimationHelper.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export default {
  data() {
    return {
      scene: null, //场景
      camera: null, //相机
      renderer: null, //渲染器
      container: null, //容器
      anId: null,
      helper: null, //动画辅助工具
      loader: null, //加载器
      controls: null, //鼠标控制
      motion: 'MMD/蔡徐坤/蔡徐坤篮球（人动作）.vmd',
      model: 'MMD/胡桃/胡桃.pmx',
      motions: [
        { name: '蔡徐坤', path: 'MMD/蔡徐坤/蔡徐坤篮球（人动作）.vmd' },
        { name: '动作2', path: 'MMD/motion/motion2.vmd' },
        { name: '动作3', path: 'MMD/motion/动作3.vmd' },
        { name: '丘丘摇', path: 'MMD/motion/丘丘摇.vmd' },
      ],
      models: [
        { name: '胡桃', path: 'MMD/胡桃/胡桃.pmx' },
        { name: '坤坤子', path: 'MMD/坤坤子/坤坤子.pmx' },
        { name: '甘雨', path: 'MMD/ganyu/甘雨.pmx' },
        { name: '八重神子', path: 'MMD/八重神子/八重神子.pmx' },
      ],
    }
  },
  components: {
    Particle,
  },
  mounted() {
    this.init()
  },
  methods: {
    play() {
      // //根据动画id停止动画渲染
      cancelAnimationFrame(this.anId)
      // //强制失去上下文
      this.renderer.forceContextLoss()
      this.renderer.dispose()
      this.scene.clear()
      this.scene = null
      this.camera = null
      this.mouseControls = null
      this.container.innerHTML = null
      this.renderer = null
      this.init()
    },
    animate() {
      this.anId = requestAnimationFrame(() => this.animate())
      if (this.helper) {
        this.helper.update(0.017) // 更新动画助手
      }
      this.renderer.render(this.scene, this.camera)
      this.loading = false
    },
    init() {
      this.loading = true
      this.container = this.$refs.sceneElement
      console.log(this.container.offsetWidth, this.container.offsetHeight)

      this.scene = new THREE.Scene()
      this.camera = new THREE.PerspectiveCamera(
        45,
        this.container.clientWidth / this.container.clientHeight,
        1,
        2000
      )
      this.camera.position.set(0, 10, 70)
      // let axes = new THREE.AxesHelper(300) //坐标系(辅助开发)
      // axes.rotation.x = 0.1
      // this.scene.add(axes)
      this.renderer = new THREE.WebGLRenderer({ alpha: true })
      this.renderer.setSize(
        this.container.clientWidth,
        this.container.clientHeight
      )
      this.container.appendChild(this.renderer.domElement)

      this.controls = new OrbitControls(this.camera, this.renderer.domElement)
      this.controls.enableDamping = true // 开启阻尼效果
      this.controls.dampingFactor = 0.05 // 阻尼系数

      const gridHelper = new THREE.PolarGridHelper(15, 0)
      this.scene.add(gridHelper)
      const ambientLight = new THREE.AmbientLight(0xffffff, 3)
      this.scene.add(ambientLight)

      this.loader = new MMDLoader()
      this.helper = new MMDAnimationHelper()

      this.animate() // 开始动画循环
      this.loader.loadWithAnimation(this.model, this.motion, (mmd) => {
        const mesh = mmd.mesh
        mesh.position.set(0, 0, 0)
        mesh.scale.set(1, 1, 1)
        this.scene.add(mesh)

        this.helper.add(mesh, {
          animation: mmd.animation,
          physics: true,
        })
      })
    },
  },
}
</script>


<style lang="scss" scoped>
.home {
  position: relative;
  background: #000;
  width: 100%;
  height: calc(100vh - 84px);
}
.button_flex {
  position: absolute;
  left: 60px;
  top: 10px;
  z-index: 9999;
  > * {
    margin: 10px;
  }
}
.scene_element {
  position: absolute;
  top: 100px;
  z-index: 11;
  width: 100%;
  height: calc(150vh);
}
</style>